/**
 * Created by game on 2016/11/14
 */
////////////////// fix Date object ///////////////////
if (!Date.isDateString) {
    Date.isDateString = function (s) { return /^[\d]+-[\d]{1,2}-[\d]{1,2}$/.test (s); }
}

if (!Date.isTimeString) {
    Date.isTimeString = function (s) {
        return /^[\d]+-[\d]{1,2}-[\d]{1,2} [\d]{1,2}:[\d]{1,2}:[\d]{1,2}/.test(s);
    }
}

if (!Date.parseDate) {
    Date.parseDate = function (s) {
        var a = s.split("-");
        var year = parseInt (a [0], 10);
        var month = parseInt (a [1], 10);
        var date = parseInt (a [2], 10);
        return new Date (year, month - 1, date);
    }
}

if (!Date.parseTime) {
    Date.parseTime = function (s) {
        var a = s.split (" ");
        var date = Date.parseDate(a [0]);
        a = a[1].split(":");

        var hour = parseInt (a[0], 10);
        var minute = parseInt (a[1], 10);
        var second = parseInt (a[2], 10);
        date.setHours(hour);
        date.setMinutes(minute);
        date.setSeconds(second);

        return date;
    }
}

Date.__MaxMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
Date.prototype.__firstDayOfWeek = 0; // sunday

Date.SUNDAY = 0;
Date.MONDAY = 1;

Date.WeekTitles = {
    "ZH-CN" : ["日", "一", "二", "三", "四", "五", "六"],
    "DEFAULT" : ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
};
Date.Week = {"ZH-CN": "星期", "DEFAULT":"Week"};
Date.MonthTitles = {
    "ZH-CN":["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
    "DEFAULT": ["Jan", "Feb", "Mar", "Apr", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
};
/*
 Date.WeekTitles = [];
 Date.WeekTitles ["ZH-CN"]   = ["日", "一", "二", "三", "四", "五", "六"];
 Date.WeekTitles ["DEFAULT"] = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

 Date.Week = [];
 Date.Week["ZH-CN"] = "星期";
 Date.Week["DEFAULT"] = "Week";
 */

/*
 Date.MonthTitles = [];
 Date.MonthTitles ["ZH-CN"] = ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"];
 Date.MonthTitles ["DEFAULT"] = ["Jan", "Feb", "Mar", "Apr", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
 */

Date.parseFromString = function (str, pattern) {
    if (!pattern) {
        var a = str.split("-");
        var year = parseInt (a [0], 10);
        var month = parseInt (a [1], 10) - 1;
        var day = parseInt (a [2], 10);
        return new Date (year, month, day);
    }

    return null;
};

Date.prototype.formatTime = function () {
    return this.format() + " " + this.getTimePart ();
};

Date.prototype.getTimePart = function () {
    var s = "";
    var hour = this.getHours();
    var minute = this.getMinutes();
    var second = this.getSeconds();
    s += (hour < 10 ? "0" : "") + hour + ":";
    s += (minute < 10 ? "0" : "") + minute + ":";
    s += (second < 10 ? "0" : "") + second;
    return s;
};

Date.prototype.setFirstDayOfWeek = function (firstDay) { this.__firstDayOfWeek = firstDay; };
Date.prototype.getFirstDayOfWeek = function () { return this.__firstDayOfWeek; };
Date.prototype.getFirstDateOfMonth = function () { return new Date (this.getFullYear(), this.getMonth(), 1); };
Date.prototype.getLastDateOfMonth = function () {
    var year = this.getFullYear();
    var month = this.getMonth();
    if (month == 1 && (year % 4 ==0 && year % 100 != 0)) return Date.__MaxMonthDays [1] + 1;
    return Date.__MaxMonthDays [month];
};

Date.prototype.getFirstDateOfWeek = function () {
    var day = this.getDay ();
    if (day == this.__firstDayOfWeek) return new Date (this.getFullYear(), this.getMonth(), this.getDate ());
    var date = new Date (this.getFullYear(), this.getMonth(), this.getDate());
    date.setDate(date.getDate () - day + this.__firstDayOfWeek);
    return date;
};

Date.prototype.getLastDateOfWeek = function () {
    var date = this.getFirstDateOfWeek();
    date.setDate (date.getDate() + 6);
    return date;
};

Date.prototype.getDateAfterThisWeek = function () {
    var date = this.getLastDateOfWeek();
    date.setDate (date.getDate() + 1);
    return date;
};

Date.prototype.getDateAfterThisMonth = function () {
    var date = new Date (this.getFullYear(), this.getMonth(), 1);
    date.setMonth (this.getMonth() + 1);
    return date;
};

Date.prototype.getNextDate = function () {
    var date = new Date (this.getFullYear(), this.getMonth(), this.getDate ());
    date.setDate (date.getDate() + 1);
    return date;
};

Date.prototype.copy = function (other) {
    this.setFullYear (other.getFullYear ());
    this.setMonth (other.getMonth ());
    this.setDate (other.getDate ());
    this.setHours (other.getHours ());
    this.setMinutes (other.getMinutes ());
    this.setSeconds (other.getSeconds ());
};

Date.prototype.clone = function () {
    var date = new Date ();
    date.copy (this);
    return date;
};

Date.prototype.format = function () {
    if (arguments.length == 0) {
        var s = this.getFullYear() + "-";
        var month = this.getMonth() + 1;
        if (month < 10) s += "0";
        s += month + "-";
        var date = this.getDate();
        if (date < 10) s += "0";
        s += date;
        return s;
    }
};

Date.prototype.formatTime = function () {
    var s = this.format();
    var hour = this.getHours();
    var minute = this.getMinutes();
    var second = this.getSeconds();
    s += (hour < 10 ? " 0" : " ") + hour + ":";
    s += (minute < 10 ? "0" : "") + minute + ":";
    s += (second < 10 ? "0" : "") + second;
    return s;
};
// implements java.util.Calendar
Date.prototype.getDayOfYear = function () {
    var year = this.getFullYear ();
    var month = this.getMonth ();
    var date = this.getDate ();
    var days = 0;
    for (var i = 0; i < month; i ++) {
        if (i == 1 && year % 4 == 0 && year % 100 != 0) days ++;
        days += Date.__MaxMonthDays [i];
    }

    days += date;
    return days;
};

Date.YEAR         = "year";
Date.QUARTER      = "quarter";
Date.MONTH        = "month";
Date.WEEK         = "week";
Date.DAY_OF_YEAR  = "day_of_year";
Date.DAY_OF_MONTH = "day_of_month";
Date.DAY_OF_WEEK  = "day_of_week";
Date.HOUR         = "hour";
Date.HOUR_OF_DAY  = "hour_of_day";
Date.MINUTE       = "minute";
Date.SECOND       = "second";
Date.MILLSECOND   = "millsecond";

Date.prototype.get = function (field) {
    switch (field) {
        case Date.YEAR : return this.getFullYear ();
        case Date.QUARTER : return this.getQuarter ();
        case Date.MONTH : return this.getMonth ();
        case Date.WEEK_OF_YEAR : return this.getWeekOfYear ();
        case Date.WEEK_OF_MONTH : return getWeekOfMonth ();
        case Date.DAY_OF_YEAR : return this.getDayOfYear ();
        case Date.DAY_OF_MONTH : return this.getDate ();
        case Date.DAY_OF_WEEK : return this.getDay ();
        case Date.HOUR : return this.getHours();
        case Date.HOUR_OF_DAY : return this.getHours();
        case Date.MINUTE : return this.getMinutes();
        case Date.SECOND : return this.getSeconds();
        case Date.MILLSECOND : return this.getMilliseconds();
        default : throw "Not support field: " + field;
    }
};

Date.prototype.set = function (field, value) {
    switch (field) {
        case Date.YEAR : this.setFullYear (value); break;
        case Date.QUARTER : this.setQuarter (value); break;
        case Date.MONTH : this.setMonth (value); break;
        case Date.DAY_OF_MONTH : this.setDate (value); break;
        case Date.DAY_OF_WEEK : this.setDay (value); break;
        case Date.HOUR : this.setHours(value); break;
        case Date.HOUR_OF_DAY : this.setHours(value); break;
        case Date.MINUTE : this.setMinutes(value); break;
        case Date.SECOND : this.setSeconds(value); break;
        case Date.MILLSECOND : this.setMilliseconds(value); break;
    }
    return this;
};

Date.prototype.getWeekOfYear = function () {
    var date = new Date (this.getFullYear (), 0, 1);
    var days = this.getDayOfYear ();
    var weeks = parseInt (days / 7) + 1;
    var first = date.getDay ();
    var last = this.getDay ();
    var delta = days % 7;
    if (first != 0 && delta > last) weeks ++;
    return weeks;
};

Date.prototype.getWeekOfMonth = function () {
    var weeks = this.getWeekOfYear ();
    var date = new Date (this.getFullYear (), this.getMonth (), this.getDate ());
    var first = date.getWeekOfYear ();
    return weeks - first + 1;
};

Date.prototype.getWeeksInMonth = function () {
    var days = Date.__MaxMonthDays [this.getMonth ()];
    var date = new Date (this.getFullYear (), this.getMonth (), 1);
    var first = date.getDay ();
    date.setDate (days);
    var last = date.getDay ();
    var weeks = parseInt (days / 7) + 1;
    var delta = days % 7;
    if (first != 0 && delta > last) weeks ++;
    return weeks;
};

Date.prototype.add = function (field, offset) { return this.set (field, this.get (field) + offset); };
Date.prototype.getQuarter = function () { return (this.getMonth () / 3) + 1; };
Date.prototype.setQuarter = function (quarter) { this.setMonth ((quarter - 1) * 3); this.setDate (1); };
//////////////// end date //////////////////////////////